﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Diagnostics;
using System.Collections;

namespace wlm.wsx.src.wlm.Newwsx
{
    class CommonData
    {
        /// <summary>
        /// 程序块
        /// </summary>
        public const string _PROGRAM = "PROGRAM";

        /// <summary>
        /// 条件
        /// </summary>
        public const string _CONDITIN = "CONDITIN";

        /// <summary>
        /// 操作集合
        /// </summary>
        public const string _OPERATION = "OPERATION";

        /// <summary>
        /// 计算
        /// </summary>
        public const string _OPERATOR = "OPERATOR"; 

        /// <summary>
        /// 判断
        /// </summary>
        public const string _IF = "IF";
        public const string _ELSEIF = "ELSEIF";
        public const string _ELSE = "ELSE";

        /// <summary>
        /// 循环
        /// </summary>
        public const string _FOR = "FOR";
        public const string _DO = "DO";
        public const string _WHILE = "WHILE";

        public const string _INT = "INT";
        public const string _FLOAT = "FLOAT";
        public const string _DOUBLE = "DOUBLE";
        public const string _STRING = "STRING";
        public const string _BOOL = "BOOL";

        private static ElementList _ElementList = new ElementList();

        /// <summary>
        /// 局部变量集合
        /// </summary>
        public static ElementList ElementList
        {
            get { return _ElementList; }
          }

        /// <summary>
        /// 添加变量
        /// </summary>
        /// <param name="node">变量节点</param>
        /// <param name="elementList">变量集合</param>
        public static void AddElement(XmlNode node, ref Element element)
        {
            if (node.Attributes["name"] == null)
                return;

            if (!_ElementList.Contains(node.Name, node.Attributes["name"].InnerText))
            {
                element = new Element();
                element.Name = node.Attributes["name"].InnerText;
                element.DataType = node.Name;
                element.Value = node.InnerText;
                _ElementList.Add(element);
            }
         }
        /// <summary>
        /// 添加变量
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="strDataType">数据类型</param>
        /// <param name="strValue">值</param>
        public static void AddElement(string strName, string strDataType,string strValue)
        {
            if (!_ElementList.Contains(strName, strDataType))
            {
                Element element = new Element();
                element.Name = strName;
                element.DataType = strDataType;
                element.Value = strValue;
               _ElementList.Add(element);
            }
        }

        /// <summary>
        /// 添加变量
        /// </summary>
        /// <param name="node">变量节点</param>
        /// <param name="elementList">变量集合</param>
        public static void AddElement(Element item)
        {
            _ElementList.Add(item);
        }

       /// <summary>
        /// 获取变量
       /// </summary>
       /// <param name="node">变量节点</param>
       /// <returns></returns>
        public static Element GetElement(XmlNode node)
        {
            if (node == null)
                return null;

            if (node.Attributes["name"] == null)
                return null;
            // 在变量集合中查找当前变量
            return GetElement(node.Attributes["name"].InnerText, node.Name,node.InnerText);
        }

        /// <summary>
        /// 获取变量
        /// </summary>
        /// <param name="strName">变量名称</param>
        /// <param name="strDataType">数据类型</param>
        /// <param name="strValue">值</param>
        /// <returns></returns>
        public static Element GetElement(string strName,string strDataType,string strValue)
        {
            //// 首先查找是否有相同的变量，如果没有则添加进变量集合中
            //if (!_ElementList.Contains(strName, strDataType))
            //    AddElement(strName, strDataType, strValue);
            // 在变量集合中查找当前变量
            return _ElementList.Find(strName, strDataType);
        }


        /// <summary>
        /// 计算解析
        /// </summary>
        /// <param name="xmlOperator">oprator节点</param>
        /// <returns></returns>
        public static void Operator(XmlNode xmlOperator, ref Element element)
        {
            // 计算类型
            string strType = string.Empty;
            // 返回结果
            string strResult = string.Empty;

             List<string> operands = new List<string>();

            // 获取计算类型
            if (xmlOperator.Attributes["type"] != null)
                strType = xmlOperator.Attributes["type"].InnerText;

            if (string.IsNullOrEmpty(strType))
                return;

            OperatorBase operatorBase = OperatorBase.CreateOperatorBase(strType);
            for(int index = 0; index < xmlOperator.ChildNodes.Count; index ++)
            //foreach (XmlNode node in xmlOperator.ChildNodes)
            {
                XmlNode node = xmlOperator.ChildNodes[index];
                // 添加查找变量
                if (node.Attributes["name"] != null)
                {
                    // 在变量集合中查找当前变量
                     element = GetElement(node.Attributes["name"].InnerText, node.Name,node.InnerText);

                      if (element == null)
                         AddElement(node,ref element);
                 }

                // 字符串连接时，把strResult最为第一个参数使用
                if (node.Name.ToUpper() == CommonData._STRING)
                {
                    // 字符串连接
                    strResult = operatorBase.OnCalculate(new string[] { strResult, node.InnerText });
                    continue;
                }

                // 如果参数个数大于2，且strResult不为空时，把参数代入计算
                if (index > 1 && !string.IsNullOrEmpty(strResult))
                {
                    operands.Add(strResult);
                }

                // 添加参数集合
                operands.Add(node.InnerText);

                // ++,--使用
                if (operatorBase is OperatorMinusMinus || operatorBase is OperatorPlusPlus)
                {
                    strResult = operatorBase.OnCalculate(new double[] { Convert.ToDouble(operands[0]) }).ToString();
                    operands.Clear();
                    continue;
                }

                // 如果是最后一个节点，同时参数集合小于2，strResult不为null或""，则把strResult带入计算，用于是奇数参数时的运算
                if (xmlOperator.LastChild.Equals(node) && operands.Count < 2 && !string.IsNullOrEmpty(strResult))
                {
                    operands.Add(strResult);
                }
                // bool判断和数值计算，参数都必须是2个
                if (operands.Count > 1)
                {
                    // 比较判断
                    if (operatorBase is OperatorCompare || operatorBase is OperatorBitAnd || operatorBase is OperatorBitOr)
                    {
                        // bool值判断
                        strResult = operatorBase.OnCalculate(new int[] { Convert.ToInt32(operands[0]), Convert.ToInt32(operands[1]) }).ToString();

                        if (element != null)
                            element.DataType = "bool";

                        if (string.IsNullOrEmpty(strResult) || strResult == "0")
                            strResult = "False";
                        else if (strResult == "1")
                            strResult = "True";
                    }
                    else
                    {
                        // 数值计算
                        strResult = operatorBase.OnCalculate(new double[] { Convert.ToDouble(operands[0]), Convert.ToDouble(operands[1]) }).ToString();
                    }
                    operands.Clear();
                 }
            }

            if (element != null)
                element.Value = strResult;
        }
    }
}
